{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# GitHub极简教程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "GitHub是一个非常流行的全球代码托管平台，基于Git版本控制技术实现，同时GitHub也是一个活跃的开发者交流社区。许多的开源项目都在GitHub上发布。例如著名的Linux操作系统内核的源代码。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Linux内核源码](https://github.com/torvalds/linux)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "GitHub是什么？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](GitHub是什么.jpg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一，Git简介\n",
    "\n",
    "Git是目前世界上最先进的分布式版本控制系统（没有之一）。\n",
    "\n",
    "它由Linux系统之父Linus Torvalds在2005年用C语言开发。\n",
    "\n",
    "Git是一个分布式版本控制系统，没有中央服务器，不同于svn等需要中央服务器的集中式版本控制系统。\n",
    "\n",
    "Git的功能：版本控制（版本管理，远程仓库，分支协作）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**人工版本管理：**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](人工版本管理.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Git版本管理：**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](git版本管理效果.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二，功能原理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* git版本控制系统由工作区，缓存区，版本库组成。\n",
    "* git跟踪的是文件的修改而不是全部文件。\n",
    "* git擅长管理代码等文本文件，不擅长管理图片等二进制文件。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](./git系统原理.jpg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 三，快速上手"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1，安装配置Git.\n",
    "\n",
    "下载位置: [Git下载链接](https://git-scm.com/downloads)—— https://git-scm.com/downloads\n",
    "\n",
    "windows下载安装后可以在Gitbash中执行git命令，也可以在Jupyter Notebook中执行."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!git config --global user.name \"lyhue1991\"\n",
    "!git config --global user.email \"lyhue1991@163.com\"\n",
    "\n",
    "# 出现一些类似 warning: LF will be replaced by CRLF in <file-name>. 可启用如下设置。\n",
    "!git config --global core.autocrlf false\n",
    "\n",
    "# 配置打印历史commit的快捷命令\n",
    "!git config --global alias.lg \"log --oneline --graph --all\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2，创建仓库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "F:\\shidayunpan\\allCCTVResearch\\PythonFiles\\GitHub\\git-learn\n"
     ]
    }
   ],
   "source": [
    "%mkdir git-learn\n",
    "%cd git-learn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initialized empty Git repository in F:/shidayunpan/allCCTVResearch/PythonFiles/GitHub/git-learn/.git/\n"
     ]
    }
   ],
   "source": [
    "!git init"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3，提交文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"hello world\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "\n",
      "No commits yet\n",
      "\n",
      "Changes to be committed:\n",
      "  (use \"git rm --cached <file>...\" to unstage)\n",
      "\n",
      "\tnew file:   readme.txt\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!git status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"add readme.txt\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4，推送远程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!git remote add origin https://github.com/lyhue1991/git-learn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Branch 'master' set up to track remote branch 'master' from 'origin'.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "To https://github.com/lyhue1991/git-learn\n",
      " * [new branch]      master -> master\n"
     ]
    }
   ],
   "source": [
    "!git push -u origin master"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "5，克隆远程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Cloning into '../liaoxuefeng'...\n"
     ]
    }
   ],
   "source": [
    "!git clone https://github.com/lyhue1991/Git-Tutorial-By-liaoxuefeng ../liaoxuefeng"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 四，常用命令列表"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**列了22个常用命令名**。\n",
    "\n",
    "**举了44个示范命令**。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](Git常用命令.bmp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 五，版本回退"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过 git reset HEAD^ 可以回退到上一个版本。\n",
    "\n",
    "通过git reset HEAD^^ 可以回退到上上个版本。\n",
    "\n",
    "通过 git reset a234b3 可以回退到版本号为 a234b3的版本。\n",
    "\n",
    "git 命令的选项如下：\n",
    "\n",
    "git reset --hard  head^   修改版本库，保留暂存区，保留工作区\n",
    "\n",
    "git reset --mixed head^  修改版本库，修改暂存区，保留工作区\n",
    "\n",
    "git reset --soft  head^  修改版本库，保留暂存区，保留工作区"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "F:\\shidayunpan\\allCCTVResearch\\PythonFiles\\GitHub\\git-learn\n"
     ]
    }
   ],
   "source": [
    "%cd git-learn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load readme.txt\n",
    "\"hello world\" \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"hello China\" >> readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt  #查看readme.txt文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master 872640d] C2\n",
      " 1 file changed, 1 insertion(+)\n"
     ]
    }
   ],
   "source": [
    "!git commit -a -m\"C2\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"hello BeiJing\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master 1c73eda] C3\n",
      " 1 file changed, 1 insertion(+)\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"C3\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* 1c73eda C3\n",
      "* 872640d C2\n",
      "* f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline --graph --all"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git reset HEAD^"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "HEAD is now at f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git reset --hard HEAD^"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline --graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 六，版本前进"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果 版本回退后想回到会退前的版本，可以用git reflog查看该版本的 commit id 进而根据版本号进行恢复。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "f7c18e9 HEAD@{0}: reset: moving to head\n",
      "f7c18e9 HEAD@{1}: reset: moving to head^\n",
      "872640d HEAD@{2}: reset: moving to head^\n",
      "1c73eda HEAD@{3}: reset: moving to head\n",
      "1c73eda HEAD@{4}: reset: moving to HEAD\n",
      "1c73eda HEAD@{5}: reset: moving to head\n",
      "1c73eda HEAD@{6}: commit: C3\n",
      "872640d HEAD@{7}: commit: C2\n",
      "f7c18e9 HEAD@{8}: commit (initial): C1\n"
     ]
    }
   ],
   "source": [
    "!git reflog"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "HEAD is now at 1c73eda C3\n"
     ]
    }
   ],
   "source": [
    "!git reset --hard 1c73eda"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is ahead of 'origin/master' by 2 commits.\n",
      "  (use \"git push\" to publish your local commits)\n",
      "\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 七，撤销修改"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要撤销工作区的修改，使用git checkout -- filename。如果文件之前已经添加到暂存区，则会用暂存区内容覆盖，如果暂存区已经被提交过了，则会用版本库中最新的版本覆盖。\n",
    "\n",
    "git checkout -- file命令中的--很重要，没有--，就变成了“切换到另一个分支”的命令。\n",
    "\n",
    "如果文件已经提交过了，但想用版本库中的最新版本文件覆盖工作区文件，可以用git reset HEAD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is up to date with 'origin/master'.\n",
      "\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%echo \"hello Haidian\">>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git checkout -- readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!git checkout -- readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 八，删除文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "删除文件也是一种修改，git跟踪的是修改而非文件。因此删除文件可以直接在工作区手动删除文件，然后add -A 再 commit即可。对于已经提交过的文件，也可以用 git rm newfile.txt 直接删除工作区和暂存区文件，然后再 commit。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo 'delete me'>> newfile.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat newfile.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master 6ed6005] add a newfile\n",
      " 1 file changed, 1 insertion(+)\n",
      " create mode 100644 newfile.txt\n"
     ]
    }
   ],
   "source": [
    "!git add -A\n",
    "!git commit -m\"add a newfile\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rm 'newfile.txt'\n"
     ]
    }
   ],
   "source": [
    "!git rm newfile.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master c213efd] delete new file\n",
      " 1 file changed, 1 deletion(-)\n",
      " delete mode 100644 newfile.txt\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"delete new file\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 九，比较文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "git diff 可以比较不同版本库的同名文件。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![git](./git的diff原理.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%echo \"hello HaiDian\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!git diff readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "diff --git a/readme.txt b/readme.txt\n",
      "index ffbdc42..9ad0098 100644\n",
      "--- a/readme.txt\n",
      "+++ b/readme.txt\n",
      "@@ -1,3 +1,4 @@\n",
      " \"hello world\" \n",
      " \"hello China\" \n",
      " \"hello BeiJing\" \n",
      "+\"hello HaiDian\" \n"
     ]
    }
   ],
   "source": [
    "!git diff --cached readme.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十，添加远程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通常可以用SSH协议和远程库通信或使用http协议和远程库通信。\n",
    "\n",
    "http协议较为方便，但SSH协议方式速度较快。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ssh-keygen -t rsa -C \"your_emial@xxx.com\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在 git bash中运行上述命令，并一路回车，在用户主目录里找到.ssh目录。\n",
    "\n",
    "目录下的id_rsa有私钥，不能泄露出去。里面的id_rsa.pub是公钥，可分享给别人。\n",
    "\n",
    "在GitHub——> settings ——> SSH Keys 页面添加SSH公钥。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ssh -T git@github.com"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再在 git bash中运行上述命令，使得本机和github建立SSH连接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 可以使用SSH地址添加远程库\n",
    "!git remote add github git@github.com:lyhue1991/git-learn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 也可以使用http地址添加远程库 #添加码云\n",
    "!git remote add gitee https://gitee.com/Python_Ai_Road/git-learn  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gitee\thttps://gitee.com/Python_Ai_Road/git-learn (fetch)\n",
      "gitee\thttps://gitee.com/Python_Ai_Road/git-learn (push)\n",
      "github\tgit@github.com:lyhue1991/git-learn (fetch)\n",
      "github\tgit@github.com:lyhue1991/git-learn (push)\n",
      "origin\thttps://github.com/lyhue1991/git-learn (fetch)\n",
      "origin\thttps://github.com/lyhue1991/git-learn (push)\n"
     ]
    }
   ],
   "source": [
    "!git remote -v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git remote remove origin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gitee\n",
      "github\n"
     ]
    }
   ],
   "source": [
    "!git remote"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十一，推送远程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用 git push 命令将当前仓库内容推送至远程仓库。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gitee\thttps://gitee.com/Python_Ai_Road/git-learn (fetch)\n",
      "gitee\thttps://gitee.com/Python_Ai_Road/git-learn (push)\n",
      "github\tgit@github.com:lyhue1991/git-learn (fetch)\n",
      "github\tgit@github.com:lyhue1991/git-learn (push)\n"
     ]
    }
   ],
   "source": [
    "!git remote -v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Branch 'master' set up to track remote branch 'master' from 'github'.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Everything up-to-date\n"
     ]
    }
   ],
   "source": [
    "!git push -u github master\n",
    "# -u表示指定github为默认远程仓库，后面就可以不加任何参数使用git push了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"Hello TianAnMen!\">>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master b3f4690] C6\n",
      " 1 file changed, 2 insertions(+)\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"C6\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "To github.com:lyhue1991/git-learn\n",
      "   c213efd..b3f4690  master -> master\n"
     ]
    }
   ],
   "source": [
    "!git push"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十二，克隆远程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "git clone可以将远程仓库克隆至本地某一目录，相当于下载。不指定仓库时，会克隆到当前目录下的一个文件夹。通常在github中把感兴趣的别人的项目fork到自己的仓库里，然后再使用clone方法下载到本地进行编辑。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "在github中左上角搜索 python教程，找到感兴趣的内容并fork之。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Cloning into '../python-basic'...\n",
      "Checking out files:  32% (38/118)   \n",
      "Checking out files:  33% (39/118)   \n",
      "Checking out files:  34% (41/118)   \n",
      "Checking out files:  35% (42/118)   \n",
      "Checking out files:  36% (43/118)   \n",
      "Checking out files:  37% (44/118)   \n",
      "Checking out files:  38% (45/118)   \n",
      "Checking out files:  39% (47/118)   \n",
      "Checking out files:  40% (48/118)   \n",
      "Checking out files:  41% (49/118)   \n",
      "Checking out files:  42% (50/118)   \n",
      "Checking out files:  43% (51/118)   \n",
      "Checking out files:  44% (52/118)   \n",
      "Checking out files:  45% (54/118)   \n",
      "Checking out files:  46% (55/118)   \n",
      "Checking out files:  47% (56/118)   \n",
      "Checking out files:  48% (57/118)   \n",
      "Checking out files:  49% (58/118)   \n",
      "Checking out files:  50% (59/118)   \n",
      "Checking out files:  51% (61/118)   \n",
      "Checking out files:  52% (62/118)   \n",
      "Checking out files:  53% (63/118)   \n",
      "Checking out files:  54% (64/118)   \n",
      "Checking out files:  55% (65/118)   \n",
      "Checking out files:  56% (67/118)   \n",
      "Checking out files:  57% (68/118)   \n",
      "Checking out files:  58% (69/118)   \n",
      "Checking out files:  59% (70/118)   \n",
      "Checking out files:  60% (71/118)   \n",
      "Checking out files:  61% (72/118)   \n",
      "Checking out files:  62% (74/118)   \n",
      "Checking out files:  63% (75/118)   \n",
      "Checking out files:  64% (76/118)   \n",
      "Checking out files:  65% (77/118)   \n",
      "Checking out files:  66% (78/118)   \n",
      "Checking out files:  67% (80/118)   \n",
      "Checking out files:  68% (81/118)   \n",
      "Checking out files:  69% (82/118)   \n",
      "Checking out files:  70% (83/118)   \n",
      "Checking out files:  71% (84/118)   \n",
      "Checking out files:  72% (85/118)   \n",
      "Checking out files:  73% (87/118)   \n",
      "Checking out files:  74% (88/118)   \n",
      "Checking out files:  75% (89/118)   \n",
      "Checking out files:  76% (90/118)   \n",
      "Checking out files:  77% (91/118)   \n",
      "Checking out files:  78% (93/118)   \n",
      "Checking out files:  79% (94/118)   \n",
      "Checking out files:  80% (95/118)   \n",
      "Checking out files:  81% (96/118)   \n",
      "Checking out files:  82% (97/118)   \n",
      "Checking out files:  83% (98/118)   \n",
      "Checking out files:  84% (100/118)   \n",
      "Checking out files:  85% (101/118)   \n",
      "Checking out files:  86% (102/118)   \n",
      "Checking out files:  87% (103/118)   \n",
      "Checking out files:  88% (104/118)   \n",
      "Checking out files:  89% (106/118)   \n",
      "Checking out files:  90% (107/118)   \n",
      "Checking out files:  91% (108/118)   \n",
      "Checking out files:  92% (109/118)   \n",
      "Checking out files:  93% (110/118)   \n",
      "Checking out files:  94% (111/118)   \n",
      "Checking out files:  95% (113/118)   \n",
      "Checking out files:  96% (114/118)   \n",
      "Checking out files:  97% (115/118)   \n",
      "Checking out files:  98% (116/118)   \n",
      "Checking out files:  99% (117/118)   \n",
      "Checking out files: 100% (118/118)   \n",
      "Checking out files: 100% (118/118), done.\n"
     ]
    }
   ],
   "source": [
    "!git clone  https://github.com/lyhue1991/python-basic ../python-basic\n",
    "    \n",
    "# 通常用 ./表示当前目录，../表示当前目录的父目录"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "F:\\shidayunpan\\allCCTVResearch\\PythonFiles\\GitHub\\python-basic\n"
     ]
    }
   ],
   "source": [
    "%cd ../python-basic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is up to date with 'origin/master'.\n",
      "\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十三，更新远程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "fetch能够获取远程仓库的更新，但不同步到本地仓库。\n",
    "fetch获取到的是修改，不会获取文件，而clone会获取文件。\n",
    "可以在fetch之后利用merge，rebase等方法合并并同步到本地。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "在github中的git-learn项目下新建一个 test.txt文件并commit。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "From github.com:lyhue1991/git-learn\n",
      " * branch            master     -> FETCH_HEAD\n"
     ]
    }
   ],
   "source": [
    "!git fetch github master"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is behind 'github/master' by 1 commit, and can be fast-forwarded.\n",
      "  (use \"git pull\" to update your local branch)\n",
      "\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Updating b3f4690..2b04eab\n",
      "Fast-forward\n",
      " test.txt | 1 +\n",
      " 1 file changed, 1 insertion(+)\n",
      " create mode 100644 test.txt\n"
     ]
    }
   ],
   "source": [
    "!git merge github/master"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十四，合并远程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "git pull 能够或取远程仓库的更新，并同步合并到本地。\n",
    "\n",
    "相当于git fetch之后再merge。有时候会有冲突，需要解决。\n",
    "\n",
    "你可以在GitHub网站上的通过fork一些开源项目的代码，然后clone到本地后，尝试完善项目，再发送pull request到项目发起人，如果项目发起人通过了你的请求，那么你就为开源项目做出了贡献。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在github中的对应git-learn的readme.txt的最后一行加上\"remote line\"并commit.\n",
    "在本地的git-learn的readme.txt的最后一行加上\"local line\"并commit.\n",
    "则会发生冲突。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"local line\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%pycat readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master 4e30082] update local\n",
      " 1 file changed, 1 insertion(+)\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"update local\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Auto-merging readme.txt\n",
      "CONFLICT (content): Merge conflict in readme.txt\n",
      "Automatic merge failed; fix conflicts and then commit the result.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "From github.com:lyhue1991/git-learn\n",
      " * branch            master     -> FETCH_HEAD\n",
      "   2b04eab..2cc5f85  master     -> github/master\n"
     ]
    }
   ],
   "source": [
    "!git pull github master"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "尝试git pull，但是出现了冲突，在本地文件打开readme.txt根据指引解决冲突。\n",
    "\n",
    "解决冲突后add,commit,push即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is up to date with 'github/master'.\n",
      "\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"solve conflict\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Everything up-to-date\n"
     ]
    }
   ],
   "source": [
    "!git push"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十五，分支创建"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通常在团队协作时经常需要使用分支功能。开发时大家在不同的分支上工作，互不冲突。\n",
    "\n",
    "到一定开发阶段再使用分支合并功能综合大家的工作结果。\n",
    "\n",
    "默认的分支为master,可以用git branch develop在当前位置创建分支。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "git分支最佳实践："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![git分支](.\\git分支最佳实践.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* master: 主分支，主要用来版本发布。\n",
    "* develop：日常开发分支，该分支正常保存了开发的最新代码。\n",
    "* feature：具体的功能开发分支，只与 develop 分支交互。\n",
    "* release：release 分支可以认为是 master 分支的未测试版。比如说某一期的功能全部开发完成，那么就将 develop 分支合并到 release 分支，测试没有问题并且到了发布日期就合并到 master 分支，进行发布。\n",
    "* hotfix：线上 bug 修复分支。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#创建和删除分支"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#在当前head位置创建分支 develop\n",
    "!git branch develop "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* 4e30082 update local\n",
      "* 2b04eab Create test.txt\n",
      "* b3f4690 C6\n",
      "* c213efd delete new file\n",
      "* 6ed6005 add a newfile\n",
      "* 1c73eda C3\n",
      "* 872640d C2\n",
      "* f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline --graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 在某个commit id 号位置创建分支 feature\n",
    "!git branch feature 1c73eda"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  develop\n",
      "  feature\n",
      "* master\n"
     ]
    }
   ],
   "source": [
    "!git branch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  develop\n",
      "  feature\n",
      "* master\n",
      "  remotes/github/master\n"
     ]
    }
   ],
   "source": [
    "# 查看包括远程同步仓库的所有分支\n",
    "!git branch -a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Deleted branch feature (was 1c73eda).\n"
     ]
    }
   ],
   "source": [
    "# 删除分支 feature\n",
    "!git branch -d feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  develop\n",
      "* master\n"
     ]
    }
   ],
   "source": [
    "!git branch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十六，分支切换"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "使用 git checkout develop 可以从当前分支切换到 develop分支。\n",
    "\n",
    "使用 git checkout -b feature 可以在当前HEAD位置创建新分支 feature 并将HEAD切换到新分支。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Switched to branch 'develop'\n"
     ]
    }
   ],
   "source": [
    "!git checkout develop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Switched to a new branch 'feature'\n"
     ]
    }
   ],
   "source": [
    "!git checkout -b feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十七，分支合并"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "merge方法可以将两个有共同祖先节点的不同分支进行合并。\n",
    "\n",
    "如果其中一个分支完全领先于另外一个分支，那么默认会采用fast forward合并方式。\n",
    "\n",
    "如果两个分支在分叉后各自都有新的commit，那么会是一种三方合并方式。\n",
    "\n",
    "第二种情况下可能需要解决冲突。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "fast forward合并方式:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](.\\git merge 快进式.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "三方合并方式："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](./git的merge原理.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "使用 no-ff模式可以保留被合并分支的原有信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](git merge --no-ff.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your branch is up to date with 'github/master'.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Switched to branch 'master'\n"
     ]
    }
   ],
   "source": [
    "!git checkout master"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!echo \"writen by master branch\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master b16a1bd] master branch\n",
      " 1 file changed, 1 insertion(+)\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"master branch\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Switched to branch 'develop'\n"
     ]
    }
   ],
   "source": [
    "!git checkout develop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"writen by develop branch\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[develop 710fa6e] develop branch\n",
      " 1 file changed, 1 insertion(+)\n"
     ]
    }
   ],
   "source": [
    "!git commit -am\"develop branch\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* 710fa6e develop branch\n",
      "| * b16a1bd master branch\n",
      "|/  \n",
      "* 4e30082 update local\n",
      "* 2b04eab Create test.txt\n",
      "* b3f4690 C6\n",
      "* c213efd delete new file\n",
      "* 6ed6005 add a newfile\n",
      "* 1c73eda C3\n",
      "* 872640d C2\n",
      "* f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline --graph --all"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your branch is ahead of 'github/master' by 1 commit.\n",
      "  (use \"git push\" to publish your local commits)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Switched to branch 'master'\n"
     ]
    }
   ],
   "source": [
    "!git checkout master"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Auto-merging readme.txt\n",
      "CONFLICT (content): Merge conflict in readme.txt\n",
      "Automatic merge failed; fix conflicts and then commit the result.\n"
     ]
    }
   ],
   "source": [
    "!git merge develop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\"hello world\" \n",
    "\"hello China\" \n",
    "\"hello BeiJing\" \n",
    "\"hello HaiDian\" \n",
    "\"Hello TianAnMen!\"\n",
    "\"local line\" \n",
    "<<<<<<< HEAD\n",
    "\"writen by master branch\" \n",
    "=======\n",
    "\"writen by develop branch\" \n",
    ">>>>>>> develop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "解决冲突后重新提交"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add -A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[master 86f7912] merged\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"merged\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十八，分支重演"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "除了使用merge方法整合不同分支的内容外，分支重演rebase也是一种整合不同分支内容的方法。\n",
    "但相对复杂一些。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](.\\git的rebase.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* 710fa6e develop branch\n",
      "| * b16a1bd master branch\n",
      "|/  \n",
      "* 4e30082 update local\n",
      "* 2b04eab Create test.txt\n",
      "* b3f4690 C6\n",
      "* c213efd delete new file\n",
      "* 6ed6005 add a newfile\n",
      "* 1c73eda C3\n",
      "* 872640d C2\n",
      "* f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline --graph --all"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 209,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "HEAD is now at b16a1bd master branch\n"
     ]
    }
   ],
   "source": [
    "!git reset --hard b16a1bd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 210,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "First, rewinding head to replay your work on top of it...\n",
      "Applying: master branch\n",
      "Using index info to reconstruct a base tree...\n",
      "M\treadme.txt\n",
      "Falling back to patching base and 3-way merge...\n",
      "Auto-merging readme.txt\n",
      "CONFLICT (content): Merge conflict in readme.txt\n",
      "Patch failed at 0001 master branch\n",
      "The copy of the patch that failed is found in: .git/rebase-apply/patch\n",
      "\n",
      "Resolve all conflicts manually, mark them as resolved with\n",
      "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n",
      "You can instead skip this commit: run \"git rebase --skip\".\n",
      "To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ".git/rebase-apply/patch:9: trailing whitespace.\n",
      "\"writen by master branch\" \n",
      "warning: 1 line adds whitespace errors.\n",
      "error: Failed to merge in the changes.\n"
     ]
    }
   ],
   "source": [
    "!git rebase develop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 211,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git add readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 212,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Applying: master branch\n"
     ]
    }
   ],
   "source": [
    "!git rebase --continue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 213,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is ahead of 'github/master' by 2 commits.\n",
      "  (use \"git push\" to publish your local commits)\n",
      "\n",
      "nothing to commit, working tree clean\n"
     ]
    }
   ],
   "source": [
    "!git commit -m\"rebase over\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 215,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your branch is ahead of 'github/master' by 2 commits.\n",
      "  (use \"git push\" to publish your local commits)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Already on 'master'\n"
     ]
    }
   ],
   "source": [
    "!git checkout master"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 217,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* c28de3a master branch\n",
      "* 710fa6e develop branch\n",
      "* 4e30082 update local\n",
      "* 2b04eab Create test.txt\n",
      "* b3f4690 C6\n",
      "* c213efd delete new file\n",
      "* 6ed6005 add a newfile\n",
      "* 1c73eda C3\n",
      "* 872640d C2\n",
      "* f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline --graph --all"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 218,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!gitk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十九，储藏管理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "如果工作只进行到一半，还没法提交。\n",
    "\n",
    "但出现了一个着急的事情需要马上切换去解决，例如修复一个临时bug。\n",
    "\n",
    "有没有什么办法呢?\n",
    "\n",
    "Git提供的stash功能非常适用于这种需要现场保存的情境。\n",
    "\n",
    "把当前工作现场“储藏”起来，等以后恢复现场后继续工作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 237,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!echo 'not done!' >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "git stash;\n",
    "git stash pop;\n",
    "git stash list;\n",
    "git stash save \"message\"\n",
    "git stash apply @{X}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!git stash list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 238,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved working directory and index state WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 239,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "stash@{0}: WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is up to date with 'github/master'.\n",
      "\n",
      "Changes not staged for commit:\n",
      "  (use \"git add <file>...\" to update what will be committed)\n",
      "  (use \"git checkout -- <file>...\" to discard changes in working directory)\n",
      "\n",
      "\tmodified:   readme.txt\n",
      "\n",
      "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n",
      "Dropped refs/stash@{0} (0d10ce6c25480aa842ebb4ecb088b562d29d1905)\n"
     ]
    }
   ],
   "source": [
    "!git stash pop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"done 50%...\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved working directory and index state WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash save \"50%done\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 243,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "stash@{0}: WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!echo \"done 75%...\" >>readme.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 245,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved working directory and index state WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 246,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "stash@{0}: WIP on master: c28de3a master branch\n",
      "stash@{1}: WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 253,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "On branch master\n",
      "Your branch is up to date with 'github/master'.\n",
      "\n",
      "Changes not staged for commit:\n",
      "  (use \"git add <file>...\" to update what will be committed)\n",
      "  (use \"git checkout -- <file>...\" to discard changes in working directory)\n",
      "\n",
      "\tmodified:   readme.txt\n",
      "\n",
      "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
     ]
    }
   ],
   "source": [
    "!git stash apply 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 254,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "stash@{0}: WIP on master: c28de3a master branch\n",
      "stash@{1}: WIP on master: c28de3a master branch\n"
     ]
    }
   ],
   "source": [
    "!git stash list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 255,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dropped refs/stash@{0} (f0d23e964be3d2a9f6234e7e23f17bc747ac9c92)\n"
     ]
    }
   ],
   "source": [
    "!git stash drop 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "F:\\shidayunpan\\allCCTVResearch\\PythonFiles\\GitHub\\git-learn\n"
     ]
    }
   ],
   "source": [
    "%cd ./git-learn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!gitk --all"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十，标签管理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "用标签记录版本号会更加方便协作管理。\n",
    "\n",
    "如果团队间按如下方式沟通将很麻烦：\n",
    "\n",
    "“请把上周一的那个版本打包发布，commit号是6a5819e...”\n",
    "\n",
    "而有了版本号将会方便许多：\n",
    "\n",
    "“请把上周一的那个版本打包发布，版本号是v1.2”\n",
    "\n",
    "标签和分支很像，都是指向commit id的指针，但标签不能移动而分支能够移动。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 221,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 当前head位置打上v2.0标签\n",
    "!git tag v2.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 222,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 在commit id 为 4e30082位置打上 v1.0标签\n",
    "!git tag v1.0 4e30082"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 224,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "v1.0\n",
      "v2.0\n"
     ]
    }
   ],
   "source": [
    "# 查看全部标签\n",
    "!git tag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 225,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "commit 4e30082dfda0cd965ed06dc2e8e5ee4e99fcdb8d\n",
      "Author: lyhue1991 <lyhue1991@163.com>\n",
      "Date:   Sat Mar 10 21:06:41 2018 +0800\n",
      "\n",
      "    update local\n",
      "\n",
      "diff --git a/readme.txt b/readme.txt\n",
      "index 998866a..e85bfb1 100644\n",
      "--- a/readme.txt\n",
      "+++ b/readme.txt\n",
      "@@ -3,3 +3,4 @@\n",
      " \"hello BeiJing\" \n",
      " \"hello HaiDian\" \n",
      " \"Hello TianAnMen!\"\n",
      "+\"local line\" \n"
     ]
    }
   ],
   "source": [
    "# 查看标签对应的版本号等信息\n",
    "!git show v1.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 228,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "To github.com:lyhue1991/git-learn\n",
      " * [new tag]         v1.0 -> v1.0\n"
     ]
    }
   ],
   "source": [
    "# 推送标签到远程\n",
    "!git push github v1.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 229,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Deleted tag 'v1.0' (was 4e30082)\n"
     ]
    }
   ],
   "source": [
    "# 删除标签\n",
    "!git tag -d v1.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "To github.com:lyhue1991/git-learn\n",
      " - [deleted]         v1.0\n"
     ]
    }
   ],
   "source": [
    "# 删除远程标签\n",
    "!git push github :refs/tags/v1.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 220,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "c28de3a master branch\n",
      "710fa6e develop branch\n",
      "4e30082 update local\n",
      "2b04eab Create test.txt\n",
      "b3f4690 C6\n",
      "c213efd delete new file\n",
      "6ed6005 add a newfile\n",
      "1c73eda C3\n",
      "872640d C2\n",
      "f7c18e9 C1\n"
     ]
    }
   ],
   "source": [
    "!git log --oneline"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
